package awd.bj.jls.webs.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.core.context.SecurityContextHolder;

import com.google.common.collect.Maps;

import awd.bj.base.model.Variables;
import awd.bj.jls.webs.api.model.User;

public class DefaultQueryParam {
	/**
	 * 把一些默认参数封装进qParam，state、page、rows、sort、order等
	 * @param request
	 * @param qParam
	 */
	public static void addDefaultQueryParam(HttpServletRequest request, QueryParam qParam, String state) {
		//String state = request.getParameter("state");
		if(state != null) {
			qParam.and("state", TermType.eq, state);
		}else {
			qParam.and("state", TermType.eq, "R2");
		}

		if (SecurityContextHolder.getContext().getAuthentication() != null) {
			User users = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			if (StringUtils.isNotBlank(users.getJsbh())){
				qParam.and("jsbh", TermType.eq, users.getJsbh());
			}
		}

		String page = request.getParameter("page");
		String rows = request.getParameter("rows");
		int pageIndex = 0;
		int pageSize = 10;
		try {
			pageIndex = Integer.valueOf(page).intValue() - 1;
			pageSize = Integer.valueOf(rows).intValue();
		} catch (NumberFormatException e) {
			//e.printStackTrace();
			System.err.println("分页参数出错！");
		}finally {
			qParam.setPageIndex(pageIndex);
			qParam.setPageSize(pageSize);
		}
		
        String sortName = request.getParameter("sort");
        if (sortName != null && sortName.indexOf("String") > 0) {
        	sortName = sortName.substring(0, sortName.length() - 6);
        }
        String orderBy = request.getParameter("order");
        
        List<Sort> sorts = new ArrayList<>();
        Sort sort = new Sort();
        if(sortName != null && orderBy != null) {
        	sort.setName(sortName);
        	sort.setOrder(orderBy);
        }else {
        	sort.setName("id");
        	sort.setOrder("desc");
		}
        sorts.add(sort);
        qParam.setSorts(sorts);
	}
	
	/**
	 * 把前台传递的参数简单处理一下
	 * @param request
	 * @param qParam
	 */
	public static QueryParam  requestUtil(HttpServletRequest request) {
		QueryParam qParam = new QueryParam();
		
		List<String> special_field = new ArrayList<>();	//定义一个list 用来存放特殊的属性名
		List<String> general_field = new ArrayList<>();	//定义一个list 用来存放普通的属性
		
		request.getParameterMap().forEach((k,v1)->{
			String v = v1[0];
			if (StringUtils.isNotBlank(v)) {
				if (k.endsWith("Start")) {	//以Start结尾的 我们定义的是 时间段的开始值
					qParam.and(k.replace("Start", ""), TermType.gte, v + " 00:00:00");
				}else if (k.endsWith("End")) {	//以End结尾的 我们定义的是 时间段的结束值
					qParam.and(k.replace("End", ""), TermType.lte, v + " 23:59:59");
				}else if (k.endsWith("Type")) {		//以Type结尾的 ，我们定义的是类型匹配值	
					String field_name = k.replace("Type", "");	//去除Type之后，得到该属性名
					String value = request.getParameter(field_name);	//获取该属性值
					if (StringUtils.isNotBlank(value)) {	//该属性有值我们才进行匹配
						//姓名和别名有点特殊，因为他们是同音和同名 类型匹配，所以单独拿出来
						if ("xm".equals(field_name)) {
							if ("同音".equals(v)){
								String tmp_xmpy = PinyinUtil.cn2Pinyin(value);
								qParam.and("xmpy",TermType.like,"%"+ tmp_xmpy +"%");
							}else {
								qParam.and("xm",TermType.like,"%"+ value +"%");
							}
						}else if ("bm".equals(field_name)){
							if ("同音".equals(v)){
								String tmp_bmty = PinyinUtil.cn2Pinyin(value);
								qParam.and("bmty",TermType.like,"%"+ tmp_bmty +"%");
							}else {
								qParam.and("bm",TermType.like,"%"+ value +"%");
							}
						}
						if("等于".equals(v)){
							qParam.and(field_name,TermType.eq,value);
						}else if("不等于".equals(v)){
							qParam.and(field_name,TermType.not,value);
						}else if("属于".equals(v)){
							qParam.and(field_name,TermType.like,"%"+ value +"%");
						}
						//因为这些是类型匹配，为了避免重复传参，把这些Type 的属性，放入一个数组中好做区分
						special_field.add(field_name);	//这里面的都是像xm，bm之类的带有xmType，bmType的字段
					}
				}else if(k.endsWith("Like")){
					String field_name = k.replace("Like", "");
					qParam.and(field_name,TermType.like,"%"+ v +"%");
				}else {
					general_field.add(k);
				}
			}
		});
		
		//最后设置普通参数的查询条件
		request.getParameterMap().forEach((k,v1)->{
			String v = v1[0];
			if (StringUtils.isNotBlank(v) //判断值非空
					&& !special_field.contains(k) 	//判断k不在上面的特殊属性
					&& general_field.contains(k) 	//判断k在我们的一般属性中
					&& "state,page,rows,sort,order,pageSize,pageIndex".indexOf(k) == -1	//判断k 不在这几个基本分页参数中，
																		//因为我们下面会调用addDefaultQueryParam方法处理分页请求
					) {
				qParam.and(k,TermType.like,"%"+ v +"%");
			}
		});
		
		//最后调用基础的分页排序等方法
		String state = request.getParameter("state");
		addDefaultQueryParam(request, qParam, state);
		return qParam;
	}
	
	/**
	 * 流程的查询参数处理
	 * @param request
	 * @param processDefinitionKey
	 * @param taskDefinitionKey
	 * @return
	 */
	public static Variables workFlowRequestUtil(HttpServletRequest request,String processDefinitionKey,String taskDefinitionKey) {
		Variables variables = new Variables();	//流程查询参数
        Map<String, Object> params = Maps.newHashMap();	//存放精确匹配的参数
        Map<String, Object> notEqualsMap = Maps.newHashMap();	//存放不等于匹配的参数
        Map<String, Object> greaterThanOrEqualMap = Maps.newHashMap();	//存放大于等于匹配的参数
        Map<String, Object> lessThanOrEqualMap = Maps.newHashMap();	//存放小于等于匹配的参数
        
		List<String> special_field = new ArrayList<>();	//定义一个list 用来存放特殊的属性名
		List<String> general_field = new ArrayList<>();	//定义一个list 用来存放普通的属性
		
		request.getParameterMap().forEach((k,v1)->{
			String v = v1[0];
			if (StringUtils.isNotBlank(v)) {
				//处理流程节点定义的信息
				if ("processDefinitionKey".equals(k)) {
					if (!processDefinitionKey.contains(",")) {
			            variables.setProcessDefinitionKey(processDefinitionKey);
			        } else {
			            variables.setProcessDefinitionKey("");
			            params.put("in", processDefinitionKey);
			        }
				}else if ("taskDefinitionKey".equals(k)) {
					 variables.setTaskDefinitionKey(taskDefinitionKey);
				}else 
				//下面是前台传输的工具栏查询条件
				if (k.endsWith("Start")) {	//以Start结尾的 我们定义的是 时间段的开始值
					greaterThanOrEqualMap.put(k.replace("Start", ""), v + " 00:00:00");
				}else if (k.endsWith("End")) {	//以End结尾的 我们定义的是 时间段的结束值
					lessThanOrEqualMap.put(k.replace("End", ""), v + " 23:59:59");
				}else if (k.endsWith("Type")) {		//以Type结尾的 ，我们定义的是类型匹配值	
					String field_name = k.replace("Type", "");	//去除Type之后，得到该属性名
					String value = request.getParameter(field_name);	//获取该属性值
					if (StringUtils.isNotBlank(value)) {	//该属性有值我们才进行匹配
						//姓名和别名有点特殊，因为他们是同音和同名 类型匹配，所以单独拿出来
						if ("xm".equals(field_name)) {
							if ("同音".equals(v)){
								String tmp_xmpy = PinyinUtil.cn2Pinyin(value);
								params.put("xmpy", tmp_xmpy);
							}else {
								params.put("xm", value);
							}
						}else if ("bm".equals(field_name)){
							if ("同音".equals(v)){
								String tmp_bmty = PinyinUtil.cn2Pinyin(value);
								params.put("bmty", tmp_bmty);
							}else {
								params.put("bm", value);
							}
						}
						if("等于".equals(v)){
							params.put(field_name, value);
						}else if("不等于".equals(v)){
							notEqualsMap.put(field_name, value);
						}else if("属于".equals(v)){
							params.put(field_name, value);
						}
						//因为这些是类型匹配，为了避免重复传参，把这些Type 的属性，放入一个数组中好做区分
						special_field.add(field_name);	//这里面的都是像xm，bm之类的带有xmType，bmType的字段
					}
				}else if(k.endsWith("Like")){
					String field_name = k.replace("Like", "");
					params.put(field_name, v);
				}else {
					general_field.add(k);
				}
			}
		});

		//最后设置普通参数的查询条件
		request.getParameterMap().forEach((k,v1)->{
			String v = v1[0];
			if (StringUtils.isNotBlank(v) //判断值非空
					&& !special_field.contains(k) 	//判断k不在上面的特殊属性
					&& general_field.contains(k) 	//判断k在我们的一般属性中
					&& "state,page,rows,sort,order,pageSize,pageIndex".indexOf(k) == -1	//判断k 不在这几个基本分页参数中，
																		//因为我们下面会调用addDefaultQueryParam方法处理分页请求
					) {
				params.put(k, v);
			}
		});
		
        variables.setParams(params);	//流程匹配参数
        variables.setNotEqualsMap(notEqualsMap);	//流程不等于匹配参数
        variables.setGreaterThanOrEqualMap(greaterThanOrEqualMap);	//流程大于匹配参数
        variables.setLessThanOrEqualMap(lessThanOrEqualMap);	//流程小于匹配参数
        
		return variables;
	}
	
}
